/*
 * To change this template
 * choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * LoginPanel.java
 *
 * Created on Jul 11, 2011, 4:19:29 PM
 */
package panels;

import conn.EMIS4Connection;
import exec.NotFoundException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.List;
import dao.LoginDao;
import dao.LoginHistoryDao;
import dao.PersonDao;
import dao.UpdateHistoryDao;
import java.util.logging.Level;
import java.util.logging.Logger;
import main.MainFrame;
import obj.Page;
import obj.Login;
import obj.LoginHistory;
import obj.Person;
import obj.UpdateHistory;
import util.Crypto;
import util.LoggedInUser;
import verification.WantsValidationStatus;

/**
 *
 * @author nknowles
 */
public class LoginPanel extends javax.swing.JPanel implements WantsValidationStatus {

  private final int MAX_TRIES = 5;
  private EMIS4Connection conn;
  private int numTries;
  private InetAddress ip;
  private List<Login> loginList;
  private Login login;
  private LoginDao loginDAO;
  private LoginHistory loginHistory;
  private LoginHistoryDao loginHistoryDAO;
  private Person person;
  private PersonDao personDAO;
  private String username, pass, firstName;
  private UpdateHistory history;
  private UpdateHistoryDao historyDAO;

  /** Creates new form LoginPanel */
  public LoginPanel() {
    initComponents();
    conn = EMIS4Connection.getInstance();
    loginDAO = new LoginDao();
    login = new Login();
    loginHistory = new LoginHistory();
    loginHistoryDAO = new LoginHistoryDao();
    person = new Person();
    personDAO = new PersonDao();
    history = new UpdateHistory();
    historyDAO = new UpdateHistoryDao();

    try {
      ip = InetAddress.getLocalHost();
    } catch (UnknownHostException ex) {
      Logger.getLogger(LoginPanel.class.getName()).log(Level.SEVERE, null, ex);
    }

    usernameTextField.setInputVerifier(new verification.TextFieldVerifier(this, usernameTextField, "Username cannot be blank", 6, 25));
    passField.setInputVerifier(new verification.PasswordFieldVerifier(this, passField, "Password cannot be blank", 6, 25));
    submitButton.setEnabled(false);
  }

  /** This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {
    java.awt.GridBagConstraints gridBagConstraints;

    warningDialog = new javax.swing.JDialog();
    warningLabel = new javax.swing.JLabel();
    tempField = new javax.swing.JTextField();
    warningButton = new javax.swing.JButton();
    jLabel1 = new javax.swing.JLabel();
    reWelcomeLabel = new javax.swing.JLabel();
    jPanel1 = new javax.swing.JPanel();
    jLabel2 = new javax.swing.JLabel();
    usernameTextField = new javax.swing.JTextField();
    jLabel3 = new javax.swing.JLabel();
    passField = new javax.swing.JPasswordField();
    submitButton = new javax.swing.JButton();

    warningDialog.setTitle("Warning!");
    warningDialog.setAlwaysOnTop(true);
    warningDialog.setMinimumSize(new java.awt.Dimension(240, 100));
    warningDialog.setModal(true);
    warningDialog.addWindowListener(new java.awt.event.WindowAdapter() {
      public void windowClosing(java.awt.event.WindowEvent evt) {
        warningDialogWindowClosing(evt);
      }
    });
    warningDialog.getContentPane().setLayout(new java.awt.GridBagLayout());

    warningLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    warningLabel.setText("Message goes here");
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    gridBagConstraints.insets = new java.awt.Insets(15, 10, 0, 10);
    warningDialog.getContentPane().add(warningLabel, gridBagConstraints);

    tempField.setVisible(false);
    tempField.setFont(new java.awt.Font("Tahoma", 2, 11));
    tempField.setText("Username");
    tempField.setMaximumSize(new java.awt.Dimension(120, 20));
    tempField.setMinimumSize(new java.awt.Dimension(120, 20));
    tempField.setPreferredSize(new java.awt.Dimension(120, 20));
    tempField.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(java.awt.event.KeyEvent evt) {
        tempFieldKeyReleased(evt);
      }
    });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.insets = new java.awt.Insets(10, 10, 0, 10);
    warningDialog.getContentPane().add(tempField, gridBagConstraints);

    warningButton.setText("OK");
    warningButton.setMaximumSize(null);
    warningButton.setMinimumSize(null);
    warningButton.setPreferredSize(null);
    warningButton.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        warningButtonActionPerformed(evt);
      }
    });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.insets = new java.awt.Insets(10, 0, 10, 0);
    warningDialog.getContentPane().add(warningButton, gridBagConstraints);

    setBackground(new java.awt.Color(210, 210, 210));
    setName("Login"); // NOI18N
    setOpaque(false);
    setLayout(new java.awt.GridBagLayout());

    jLabel1.setFont(new java.awt.Font("Tahoma", 1, 24));
    jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    jLabel1.setText("Electronic Medical Information System");
    jLabel1.setMaximumSize(null);
    jLabel1.setMinimumSize(null);
    jLabel1.setPreferredSize(null);
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.insets = new java.awt.Insets(15, 0, 0, 0);
    add(jLabel1, gridBagConstraints);

    reWelcomeLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    reWelcomeLabel.setText("<html><a href>Return to welcome screen</a></html>");
    reWelcomeLabel.setMaximumSize(null);
    reWelcomeLabel.setNextFocusableComponent(usernameTextField);
    reWelcomeLabel.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseEntered(java.awt.event.MouseEvent evt) {
        reWelcomeLabelMouseEntered(evt);
      }
      public void mouseExited(java.awt.event.MouseEvent evt) {
        reWelcomeLabelMouseExited(evt);
      }
      public void mouseReleased(java.awt.event.MouseEvent evt) {
        reWelcomeLabelMouseReleased(evt);
      }
    });
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 2;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.insets = new java.awt.Insets(6, 0, 15, 0);
    add(reWelcomeLabel, gridBagConstraints);

    jPanel1.setMaximumSize(null);
    jPanel1.setOpaque(false);

    jLabel2.setText("Username:");
    jPanel1.add(jLabel2);

    usernameTextField.setMaximumSize(null);
    usernameTextField.setMinimumSize(null);
    usernameTextField.setNextFocusableComponent(passField);
    usernameTextField.setPreferredSize(new java.awt.Dimension(120, 20));
    jPanel1.add(usernameTextField);

    jLabel3.setText("Password:");
    jPanel1.add(jLabel3);

    passField.setMaximumSize(null);
    passField.setMinimumSize(null);
    passField.setNextFocusableComponent(submitButton);
    passField.setPreferredSize(new java.awt.Dimension(120, 20));
    passField.addKeyListener(new java.awt.event.KeyAdapter() {
      public void keyReleased(java.awt.event.KeyEvent evt) {
        passFieldKeyReleased(evt);
      }
    });
    jPanel1.add(passField);

    submitButton.setText("Submit");
    submitButton.setNextFocusableComponent(reWelcomeLabel);
    submitButton.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        submitButtonMouseClicked(evt);
      }
    });
    jPanel1.add(submitButton);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 1;
    gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
    gridBagConstraints.insets = new java.awt.Insets(6, 0, 0, 0);
    add(jPanel1, gridBagConstraints);

    getAccessibleContext().setAccessibleName("Login");
  }// </editor-fold>//GEN-END:initComponents

    private void reWelcomeLabelMouseReleased(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_reWelcomeLabelMouseReleased
      MainFrame mainFrame = MainFrame.getInstance();
      Page page = new Page();
      page.setTitle("Welcome");
      mainFrame.setPanel(page);
    }//GEN-LAST:event_reWelcomeLabelMouseReleased

    private void submitButtonMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_submitButtonMouseClicked
      username = usernameTextField.getText();
      pass = String.valueOf(passField.getPassword());
      // pass = Crypto.getMD5Hash(pass);


      if (submitButton.isEnabled()) {
        login.setUsername(username);

        if (numTries < MAX_TRIES) {
          try {
            conn.connect();
            loginList = loginDAO.searchMatching(conn.getConnection(), login);
            if (loginList.isEmpty()) {  // username not found
              popupWarning("User does not exists!");
              usernameTextField.selectAll();
              usernameTextField.requestFocusInWindow();
              return;
            } else {
              login = loginList.get(0);

              // Wrong password
              if (!(login.getPassword().equals(pass))) {
                // TODO add history entry for failed login??
                popupWarning("Incorrect password!");
                numTries++;
                passField.selectAll();
                passField.requestFocusInWindow();

                // Lock account after 5 unsuccessful login attempts
                if (numTries == MAX_TRIES) {
                  login.setLocked(true);
                  loginDAO.save(conn.getConnection(), login);
                  history.setAll("Login", login.getPersonID(), "Locked", "Locked Account. Too many failed log in attempts", "False", "True");
                  historyDAO.create(conn.getConnection(), history);
                }
              } else {
                // Correct username and password
                if (login.getLocked() == false) {
                  numTries = 0;
                  person = personDAO.getObject(conn.getConnection(), login.getPersonID());
                  // Inactive account
                  if (!person.getActiveStatus()) {
                    firstName = person.getFirstName();
                    tempField.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
                    tempField.setText("Enter First name");
                    tempField.selectAll();
                    tempField.setVisible(true);
                    warningButton.setEnabled(false);
                    popupWarning("Account is inactive. Please type in your First name to re-activate.");
                  } else { // Account active
                    // Store userID
                    LoggedInUser loggedInUser = LoggedInUser.getInstance();
                    loggedInUser.setRoleID(person.getRoleID());
                    loggedInUser.setUserID(login.getPersonID());
                    loggedInUser.setUsername(login.getUsername());

                    // Update user action history
                    loginHistory.setPerson_ID(loggedInUser.getUserID());
                    loginHistory.setIP_Address(ip.getHostAddress());
                    loginHistory = loginHistoryDAO.create(conn.getConnection(), loginHistory);
                    history.setAll("Login_History", loginHistory.getID(), "New Entry", "Successful Login", "", "New Login_History");
                    historyDAO.create(conn.getConnection(), history);

                    MainFrame mainFrame = MainFrame.getInstance();
                    Page page = new Page();
                    page.setTitle("Dashboard");
                    mainFrame.setPanel(page);
                  }
                } else {
                  popupWarning("Account " + username.toUpperCase() + " is LOCKED."
                          + " Please see system admin for assistance.");
                }
              }
            }
          } catch (SQLException ex) {
            Logger.getLogger(LoginPanel.class.getName()).log(Level.SEVERE, null, ex);
            return;
          } catch (NotFoundException ex) {
            Logger.getLogger(LoginPanel.class.getName()).log(Level.SEVERE, null, ex);
            return;
          }
        } else {
          /*
           * For now this just displays if the user has unsucessfully tried
           * to login 5 times in a row without restarting the app
           */
          popupWarning("Account " + username.toUpperCase() + " is now LOCKED. "
                  + "Account locked because of too many failed log in attempts!. "
                  + "Please see system admin to unlock.");
        }
      }
    }//GEN-LAST:event_submitButtonMouseClicked

  /**
   * Displays a popup window with the specified message "msg"
   * @param msg The message to be displayed on the popup window.
   */
  private void popupWarning(String msg) {
    warningLabel.setText(msg);
    warningDialog.pack();
    warningDialog.setLocationRelativeTo(this.getParent());
    warningDialog.setVisible(true);
  }

  private boolean checkAll() {
    if (usernameTextField.getText().length() < 6) {
      return false;
    }
    if (passField.getPassword().length < 6) {
      return false;
    }
    return true;
  }

    private void warningButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_warningButtonActionPerformed
      warningDialog.setVisible(false);
      if (tempField.isVisible()) {
        if (firstName.equals(tempField.getText())) {
          // Account activated
          person.setActiveStatus(true);
          try {
            personDAO.save(conn.getConnection(), person);
          } catch (NotFoundException ex) {
            Logger.getLogger(LoginPanel.class.getName()).log(Level.SEVERE, null, ex);
          } catch (SQLException ex) {
            Logger.getLogger(LoginPanel.class.getName()).log(Level.SEVERE, null, ex);
          }
          MainFrame mainFrame = MainFrame.getInstance();
          Page page = new Page();
          page.setTitle("Dashboard");
          mainFrame.setPanel(page);
        }
      }
    }//GEN-LAST:event_warningButtonActionPerformed

    private void warningDialogWindowClosing(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_warningDialogWindowClosing
      this.setVisible(true);
    }//GEN-LAST:event_warningDialogWindowClosing

    private void reWelcomeLabelMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_reWelcomeLabelMouseEntered
      reWelcomeLabel.setText("<html><i><a href>Return to welcome screen</a></i></html>");
    }//GEN-LAST:event_reWelcomeLabelMouseEntered

    private void reWelcomeLabelMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_reWelcomeLabelMouseExited
      reWelcomeLabel.setText("<html><a href>Return to welcome screen</a></html>");
    }//GEN-LAST:event_reWelcomeLabelMouseExited

private void tempFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tempFieldKeyReleased
  if (firstName.equals(tempField.getText())) {
    warningButton.setEnabled(true);
  } else {
    warningButton.setEnabled(false);
  }
}//GEN-LAST:event_tempFieldKeyReleased

private void passFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_passFieldKeyReleased
  if (passField.getPassword().length >= 6) {
    submitButton.setEnabled(true);
  } else {
    submitButton.setEnabled(false);
  }
}//GEN-LAST:event_passFieldKeyReleased
  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JLabel jLabel1;
  private javax.swing.JLabel jLabel2;
  private javax.swing.JLabel jLabel3;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JPasswordField passField;
  private javax.swing.JLabel reWelcomeLabel;
  private javax.swing.JButton submitButton;
  private javax.swing.JTextField tempField;
  private javax.swing.JTextField usernameTextField;
  private javax.swing.JButton warningButton;
  private javax.swing.JDialog warningDialog;
  private javax.swing.JLabel warningLabel;
  // End of variables declaration//GEN-END:variables

  @Override
  public void validateFailed() {
    submitButton.setEnabled(false);
  }

  @Override
  public void validatePassed() {
    if (checkAll()) {
      submitButton.setEnabled(true);
    }
  }
}
